/*
 * @FileName: [CaptchaServlet.java]
 * 
 * @Package com.bcinfo.upp.admin.ac.servlet
 * 
 * 
 * Copyright (c) 2011-2015 BCINFO Technology Limited Com. All rights reserved.
 * 
 * This software is the confidential and proprietary information of BCINFO Technology Limited Company ("Confidential Information"). You shall not disclose such Confidential Information and shall use it only in accordance with the terms of the contract agreement you entered into with RKY.
 * 
 * $Rev: 5 $ $LastChangedDate: 2013-10-12 10:19:36 +0800 (周六, 2013-10-12) $ $LastChangedBy: huangb $
 * 
 * @category bcinfo-upp
 * 
 * @version 1.1
 * 
 * @author $Author: huangb $
 * 
 * Change History:[Formatter: author date description] <br/> 1 2 3
 */

package com.bci.pwtz.servlet;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

/**
 * 生成图形验证码 <br/>
 * <p>
 * Description:<br/>
 * <p>
 * TODO 详细描述
 * 
 * <p>
 * For Examples <br/>
 * 
 * <PRE>
 *      TODO 代码使用示例
 * </PRE>
 * <p>
 */
public class CaptchaServlet implements Servlet
{

    /**
     * 生成的图形验证码输入流
     */
    private ByteArrayInputStream _image;
    /**
     * 图形验证码中的字符串
     */
    private String               _str;

    /**
     * 
     * 初始化图形验证的属性 <br/>
     * <p>
     * Description: 初始化图形验证码的输入流和验证码字符串 <br/>
     * <p>
     * Author: yangzq<br/>
     * <p>
     * Date: 2013-4-23-下午3:54:49<br/>
     * <p>
     * 
     */
    private void init()
    {
        // 在内存中创建图象
        int width = 62, height = 26;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 获取图形上下文
        Graphics g = image.getGraphics();
        // 生成随机类
        Random random = new Random();
        // 设定背景色
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);
        // 设定字体
        g.setFont(new Font("Times New Roman", Font.PLAIN, 21));
        // 随机产生155条干扰线，使图象中的认证码不易被其它程序探测到
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++)
        {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }
        // 取随机产生的认证码(6位数字)
        String sRand = "";
        for (int i = 0; i < 4; i++)
        {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            // 将认证码显示到图象中
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            // 调用函数出来的颜色相同，可能是因为种子太接近，所以只能直接生成
            g.drawString(rand, 13 * i + 6, 16);
        }
        // 赋值验证码
        this._str = sRand;

        // 图象生效
        g.dispose();
        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try
        {
            ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
            ImageIO.write(image, "JPEG", imageOut);
            imageOut.close();
            input = new ByteArrayInputStream(output.toByteArray());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        this._image = input;/* 赋值图像 */
    }

    /*
     * 给定范围获得随机颜色
     */
    private Color getRandColor(int fc, int bc)
    {
        Random random = new Random();
        if (fc > 255)
            fc = 255;
        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    /*
     * (non-Javadoc) Description: <br/>
     * 
     * @param arg0
     * 
     * @param arg1
     * 
     * @throws ServletException
     * 
     * @throws IOException
     * 
     * @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
     */
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException
    {
        init();
        ((HttpServletRequest) request).getSession().setAttribute("imageCode", _str);
        try
        {
            OutputStream os = response.getOutputStream();
            byte[] buf = new byte[_image.available()];
            _image.read(buf);
            os.flush();
            os.write(buf);
            _image.close();
            os.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    /*
     * (non-Javadoc) Description: <br/>
     * 
     * @see javax.servlet.Servlet#destroy()
     */
    public void destroy()
    {

    }

    /*
     * (non-Javadoc) Description: <br/>
     * 
     * @return
     * 
     * @see javax.servlet.Servlet#getServletConfig()
     */
    public ServletConfig getServletConfig()
    {
        return null;
    }

    /*
     * (non-Javadoc) Description: <br/>
     * 
     * @return
     * 
     * @see javax.servlet.Servlet#getServletInfo()
     */
    public String getServletInfo()
    {
        return null;
    }

    /*
     * (non-Javadoc) Description: <br/>
     * 
     * @param arg0
     * 
     * @throws ServletException
     * 
     * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig)
     */
    public void init(ServletConfig arg0) throws ServletException
    {
    }

}
